/**
 * 阿里云 OSS 文件上传工具
 * 
 * 功能说明：
 * - 提供文件上传到阿里云 OSS 的完整功能
 * - 支持单文件上传和批量上传
 * - 包含文件类型、大小验证
 * - 支持文件删除功能
 * - 自动生成唯一文件名，避免冲突
 * 
 * 技术实现：
 * - 使用阿里云官方 OSS SDK (ali-oss)
 * - 直接在前端进行文件上传，无需后端代理
 * - 支持 HTTPS 安全传输
 * - 包含完善的错误处理机制
 * 
 * 安全提醒：
 * - 当前配置在前端暴露了 AccessKeySecret，仅用于开发测试
 * - 生产环境建议使用 STS 临时凭证或后端代理上传
 */

import OSS from 'ali-oss'
import { OSS_CONFIG, generateFileName, validateFileType, validateFileSize } from '../config/ossConfig'

/**
 * 创建 OSS 客户端实例
 * 
 * 功能说明：
 * - 初始化阿里云 OSS SDK 客户端
 * - 配置认证信息和连接参数
 * - 设置安全传输和超时参数
 * 
 * @returns OSS 客户端实例
 */
const createOSSClient = () => {
  return new OSS({
    region: OSS_CONFIG.region, // OSS 区域
    accessKeyId: OSS_CONFIG.accessKeyId, // 访问密钥 ID
    accessKeySecret: OSS_CONFIG.accessKeySecret, // 访问密钥 Secret
    bucket: OSS_CONFIG.bucket, // 存储桶名称
    endpoint: OSS_CONFIG.endpoint, // 服务端点
    secure: true, // 强制使用 HTTPS 安全传输
    timeout: 60000, // 请求超时时间：60秒
  })
}

/**
 * 上传单个文件到阿里云 OSS
 * 
 * 功能说明：
 * - 验证文件类型和大小是否符合要求
 * - 生成唯一的文件名避免冲突
 * - 直接上传到阿里云 OSS 存储
 * - 返回文件的访问 URL
 * 
 * 验证规则：
 * - 文件类型：仅支持图片格式（JPEG、PNG、GIF、WebP）
 * - 文件大小：最大 10MB
 * - 文件名：自动生成唯一标识，避免覆盖
 * 
 * @param file 要上传的文件对象
 * @param _onProgress 上传进度回调函数（暂未实现）
 * @returns Promise<string> 上传成功后的文件访问 URL
 * @throws Error 当文件验证失败或上传失败时抛出错误
 */
export const uploadToOSS = async (
  file: File,
  _onProgress?: (progress: number) => void
): Promise<string> => {
  try {
    // ==================== 文件验证阶段 ====================
    
    // 验证文件类型是否允许
    if (!validateFileType(file)) {
      throw new Error(`不支持的文件类型，只支持: ${OSS_CONFIG.allowedTypes.join(', ')}`)
    }

    // 验证文件大小是否超限
    if (!validateFileSize(file)) {
      throw new Error(`文件大小不能超过 ${Math.round(OSS_CONFIG.maxFileSize / 1024 / 1024)}MB`)
    }

    // ==================== 文件处理阶段 ====================
    
    // 生成唯一的文件名（包含时间戳和随机字符串）
    const fileName = generateFileName(file.name)

    // ==================== 上传执行阶段 ====================
    
    // 创建 OSS 客户端实例
    const client = createOSSClient()

    // 执行文件上传到 OSS
    const result = await client.put(fileName, file)

    // ==================== 结果处理阶段 ====================
    
    // 记录上传结果（用于调试）
    console.log('OSS 上传成功:', {
      fileName: result.name,
      url: result.url
    })
    
    // 返回文件的访问 URL
    return result.url
  } catch (error) {
    // 记录详细的错误信息
    console.error('OSS 上传失败:', {
      fileName: file.name,
      fileSize: file.size,
      fileType: file.type,
      error: error
    })
    throw error
  }
}



/**
 * 从阿里云 OSS 删除文件
 * 
 * 功能说明：
 * - 根据文件 URL 提取文件名
 * - 从 OSS 存储中删除指定文件
 * - 释放存储空间
 * 
 * 使用场景：
 * - 用户删除已上传的图片
 * - 清理不需要的文件
 * - 节省存储成本
 * 
 * @param fileUrl 要删除的文件的完整 URL
 * @returns Promise<void> 删除操作完成
 * @throws Error 当 URL 无效或删除失败时抛出错误
 */
export const deleteFromOSS = async (fileUrl: string): Promise<void> => {
  try {
    // ==================== URL 解析阶段 ====================
    
    // 从完整的文件 URL 中提取文件名
    // 例如：https://zuomayi.oss-cn-beijing.aliyuncs.com/consultation/123456.jpg
    // 提取结果：123456.jpg
    const fileName = fileUrl.split('/').pop()
    
    // 验证文件名是否有效
    if (!fileName) {
      throw new Error('无效的文件 URL，无法提取文件名')
    }

    // ==================== 删除执行阶段 ====================
    
    // 创建 OSS 客户端实例
    const client = createOSSClient()

    // 执行文件删除操作
    await client.delete(fileName)
    
    // 记录删除成功信息
    console.log('OSS 文件删除成功:', {
      fileName: fileName,
      originalUrl: fileUrl
    })
  } catch (error) {
    // 记录详细的错误信息
    console.error('删除 OSS 文件失败:', {
      fileUrl: fileUrl,
      error: error
    })
    throw error
  }
}
